package com.tsd.system.service.impl;

import com.tsd.core.constants.Constants;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.vo.HlpException;
import com.tsd.core.vo.PageBean;
import com.tsd.service.BaseServiceImpl;
import com.tsd.system.dao.SysAccountSetMapper;
import com.tsd.system.dao.SysAccountSetResourceMapper;
import com.tsd.system.dao.SysResourceMapper;
import com.tsd.system.entity.*;
import com.tsd.system.service.SysAccountSetResourceService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述：SysAccountSetResource 服务实现层
 *
 * @author huawei
 * @date 2022/03/05 11:49:46
 */
@Service
public class SysAccountSetResourceServiceImpl extends BaseServiceImpl implements SysAccountSetResourceService {

    @Resource
    private SysAccountSetResourceMapper sysAccountSetResourceMapper;
    @Resource
    private SysAccountSetMapper sysAccountSetMapper;
    @Resource
    private SysResourceMapper sysResourceMapper;

    @Override
    public SysAccountSetResource getSysAccountSetResourceById(Long id) throws Exception {
        return sysAccountSetResourceMapper.selectByPrimaryKey(id);
    }

    @Override
    public SysAccountSetResourceExt queryBySid(String sid) throws Exception {
        return sysAccountSetResourceMapper.selectBySid(sid);
    }

    @Override
    public void deleteSysAccountSetResources(List<String> list, SysUser opUser) throws Exception {
        for (String sid : list) {
            SysAccountSetResource old = sysAccountSetResourceMapper.selectBySid(sid);
            super.checkEmpty(old, "该记录不存在");
            super.autoInjectBaseData(old, opUser, TYPE_DELETE);
            sysAccountSetResourceMapper.updateByPrimaryKeySelective(old);
        }
    }

    @Override
    public void saveSysAccountSetResource(SysAccountSetResource record, SysUser opUser) throws Exception {
        if (HlpUtils.isEmpty(record.getId())) {
            SysAccountSetResourceExt old = sysAccountSetResourceMapper.selectSameByEntity(record);
            if (old == null) {
                super.autoInjectBaseData(record, opUser, TYPE_CREATE);
                sysAccountSetResourceMapper.insertSelective(record);
            }
        } else {
            super.autoInjectBaseData(record, opUser, TYPE_UPDATE);
            sysAccountSetResourceMapper.updateByPrimaryKeySelective(record);
        }
        //不管新增还是编辑，都需要进行更新，以便同步已有系统的资源变化
        //TODO 有个问题，在账套中对角色进行设置某个树干上所有的叶子后，总账套在叶子的同层增加一个资源，再次授权同步后，之前的角色的授权应该变成半选，否则在角色授权界面显示的是所有，再次保存时，自动将所有叶子也进行了授权，其实也可以，原来是全选的，新增资源还是全选（还没有真正生效），需要手动对角色重新授权才生效
        SysResourceExt resourceExt = sysResourceMapper.selectBySid(record.getResource_sid());
        if (resourceExt != null) {
            String full_code = resourceExt.getFull_code() + "%";
            addResource2Account(record.getAccount_set_sid(), full_code);
        } else {
            throw new HlpException("资源不存在：" + record.getResource_sid());
        }
    }

    private void addResource2Account(String account_set_sid, String full_code) {
        SysAccountSetExt sysAccountSetExt = sysAccountSetMapper.selectBySid(account_set_sid);
        if (sysAccountSetExt != null) {
            sysResourceMapper.addResourceFromMaster(sysAccountSetExt.getDb_name(), full_code);
        }
    }

    private void deleteResourceFromAccount(String account_set_sid, String full_code) {
        SysAccountSetExt sysAccountSetExt = sysAccountSetMapper.selectBySid(account_set_sid);
        if (sysAccountSetExt != null) {
            sysResourceMapper.deleteRoleResourceByAccoutSetAndRes(sysAccountSetExt.getDb_name(), full_code);
            sysResourceMapper.deleteByAccoutSetAndRes(sysAccountSetExt.getDb_name(), full_code);
        }
    }

    @Override
    public List<SysAccountSetResourceExt> findSysAccountSetResources(Map<String, Object> params, PageBean page) throws Exception {
        return sysAccountSetResourceMapper.selectByPage(params, page);
    }

    @Override
    public List<SysAccountSetResourceExt> findSysAccountSetResources(Map<String, Object> params) throws Exception {
        return sysAccountSetResourceMapper.selectByParams(params);
    }

    @Override
    public List<SysAccountSetResourceExt> findSysAccountSetResourcesByAccountSetSid(String accountSetSid) throws Exception {
        super.checkEmpty(accountSetSid, "缺少参数accountSetSid");
        Map<String, Object> params = new HashMap<>();
        params.put(Constants.HEADER_NAME_ACCOUNT_SET_SID, accountSetSid);
        return sysAccountSetResourceMapper.selectByParams(params);
    }

    @Override
    public void saveSysAccountSetResources(String accountSetSid, List<SysAccountSetResourceExt> list, SysUser opUser) throws Exception {
        //先判断提交的记录属于同一个账套，然后构建需要删除和需要新增的记录
        //对删除的记录，删除Sys_Account_Set_Resource和sys_resource里面对应的数据
        //对新增的记录，同时插入Sys_Account_Set_Resource和sys_resource里面对应的数据
        super.checkEmpty(accountSetSid, "accountSetSid不能为空");
        for (SysAccountSetResource t : list) {
            if (!accountSetSid.equals(t.getAccount_set_sid())) {
                throw new HlpException("保存的资源必须属于同一个账套");
            }
        }
        List<SysAccountSetResourceExt> olds = findSysAccountSetResourcesByAccountSetSid(accountSetSid);
        List<SysAccountSetResourceExt> dels = new ArrayList<>();
        for (SysAccountSetResourceExt old : olds) {
            boolean has = false;
            for (SysAccountSetResource t : list) {
                if (old.getSid().equals(t.getSid())) {
                    has = true;
                    break;
                }
            }
            if (!has) {
                dels.add(old);
            }
        }
        for (SysAccountSetResourceExt del : dels) {
            sysAccountSetResourceMapper.deleteByPrimaryKey(del.getId());
            SysResourceExt resourceExt = sysResourceMapper.selectBySid(del.getResource_sid());
            if (resourceExt != null) {
                String full_code = resourceExt.getFull_code() + "%";
                deleteResourceFromAccount(del.getAccount_set_sid(), full_code);
            } else {
                throw new HlpException("资源不存在：" + del.getResource_sid());
            }
        }
        list.removeAll(dels);
        for (SysAccountSetResource t : list) {
            this.saveSysAccountSetResource(t, opUser);
        }
    }

    @Override
    public List<SysAccountSetResourceExt> findSysAccountSetResources4Setting(String account_set_sid) throws Exception {
        Map<String, Object> map = new HashMap<>();
        map.put(Constants.HEADER_NAME_ACCOUNT_SET_SID, account_set_sid);
        return sysAccountSetResourceMapper.selectList4Setting(map);
    }
}
